package com.uam.core.lk.utils;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.apache.kafka.common.errors.SerializationException;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @author 祝展
 * @version 1.0
 * @description
 * @Date 2020/3/26 12:04
 **/
public class DeepCopy {

    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
    private static JavaType javaType;
    private static ObjectMapper objectMapper ;

    static  {
        javaType =getJavaType(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        objectMapper = mapper;
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.disable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
    }

    private static JavaType getJavaType(Class<?> clazz) {
        return TypeFactory.defaultInstance().constructType(clazz);
    }

    public static Object deserialize(byte[] bytes) {
        try {
            return bytes == null ? null : objectMapper.readValue(bytes, 0, bytes.length, javaType);
        } catch (IOException e) {
            SerializationException exception =  new SerializationException("Error when KafkaDeserializer deserializing byte[] to string due to unsupported",e);
            throw  exception;
        }
    }

    public static byte[] serialize(Object t) {
        try {
            byte[] bytes =  t == null ? null : objectMapper.writeValueAsBytes(t);
            return bytes;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            SerializationException exception =  new SerializationException("Error when KafkaSerializer serializing Object to byte[] due to unsupported",e);
            throw  exception;
        }
    }

    public static Object copy(Object t){
        byte[] bytes = serialize(t);
        Object ret = deserialize(bytes);
        return ret;
    }
}
